package cn.edu.xmu.oomall.customer.service;

import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.oomall.customer.dao.CustomerDao;
import cn.edu.xmu.oomall.customer.model.bo.Customer;
import cn.edu.xmu.oomall.customer.model.po.CustomerPo;
import cn.edu.xmu.oomall.customer.model.vo.*;
import cn.edu.xmu.oomall.core.util.Common;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static cn.edu.xmu.privilegegateway.annotation.util.Common.cloneVo;
import static cn.edu.xmu.privilegegateway.annotation.util.Common.setPoModifiedFields;

/**
 * @author: zhang yu
 * @date: 2021/12/8 17:42
 * @version: 1.0
*/
@Service
public class CustomerService {
    @Autowired
    CustomerDao customerDao;

    private static Byte BEDELETED=(byte)1;

    /*获取顾客所有状态*/
    public ReturnObject getAllStates()
    {
        List<Map<String,Object>> stateList;
        stateList = new ArrayList<>();
        for(Customer.State state:Customer.State.values()){
            Map<String,Object> temp=new HashMap<>();
            temp.put("code",state.getCode());
            temp.put("name",state.getDescription());
            stateList.add(temp);
        }
        return new ReturnObject(stateList);
    }
    /*注册用户*/
    public ReturnObject registerUser(CustomerVo vo)
    {
        Customer customer= cloneVo(vo,Customer.class);
        ReturnObject returnObject=customerDao.insertUser(customer);
        if(returnObject.getData()!=null)
        {
            CustomerPo po=(CustomerPo)returnObject.getData();
            SimpleCustomerRetVo retVo=cloneVo(po,SimpleCustomerRetVo.class);
            return new ReturnObject(retVo);
        }
        return returnObject;
    }

    /**
     * 用户登录，并且发送邮件
     * @param loginCustomer
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject login(LoginCustomer loginCustomer)
    {
        Customer customer=new Customer();
        customer.setUserName(loginCustomer.getUserName());
        ReturnObject returnObject=customerDao.selectUserByIndex(customer);
        //判断用户是否存在
        if(returnObject.getData()==null)
        {
            return new ReturnObject(ReturnNo.CUSTOMER_INVALID_ACCOUNT);
        }
        else
        {

            List<CustomerPo> pos=(List<CustomerPo>) returnObject.getData();
            if(!(pos.size()>0))
            {
                return new ReturnObject(ReturnNo.CUSTOMER_INVALID_ACCOUNT);
            }
            CustomerPo po=pos.get(0);
            //判断用户状态是否被封禁 是否已经删除
            if(po.getState()!=null&&po.getState().equals(Customer.State.FORBIDDEN.getCode())||po.getBeDeleted()!=null&&po.getBeDeleted().equals(1))
            {
                return new ReturnObject(ReturnNo.CUSTOMER_FORBIDDEN);
            }
            //校验用户密码是否正确
            if(!po.getPassword().equals(loginCustomer.getPassword()))
            {
                return new ReturnObject(ReturnNo.CUSTOMER_INVALID_ACCOUNT);
            }
            return customerDao.createtoken(po);
        }
    }

    /**
     * 退出登录,删除服务器端token
     * @param userId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject logout(Long userId)
    {
        return customerDao.Logout(userId);
    }

    /**
     * 查询用户详细信息
     * @param userId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject getUserInfo(Long userId)
    {
        ReturnObject returnObject=customerDao.selectUserById(userId);
        if(returnObject.getData()==null)
        {
            return returnObject;
        }
        CustomerPo po=(CustomerPo) returnObject.getData();
        CustomerRetVo vo=cloneVo(po,CustomerRetVo.class);
        return new ReturnObject(vo);
    }

    /**
     * 管理员条件查询用户信息
     * @param userName
     * @param email
     * @param mobile
     * @param page
     * @param pageSize
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject getAllUserInfo(String userName,String email,String mobile,Integer page,Integer pageSize)
    {
        Customer customer=new Customer();
        customer.setUserName(userName);
        customer.setEmail(email);
        customer.setMobile(mobile);
        ReturnObject returnObject=customerDao.selectAllUser(customer,page,pageSize);
        if(returnObject.getData()!=null)
        {
            List<CustomerPo> customerPos=(List<CustomerPo>) returnObject.getData();
            PageInfo pageInfo = PageInfo.of(customerPos);
            ReturnObject returnObject1= new ReturnObject(pageInfo);
            return Common.getPageRetVo(returnObject1,SimpleCustomerRetVo.class);
        }
        return returnObject;
    }

    /**
     * 用户修改真实姓名
     * @param userId
     * @param vo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject changeUserInfo(Long userId, SimpleCustomerVo vo)
    {
        Customer customer=cloneVo(vo,Customer.class);
        customer.setId(userId);
        customer.setState(Customer.State.NORAML.getCode());
        ReturnObject returnObject=customerDao.updateUser(customer);
        if(returnObject.getData()!=null)
        {
            return new ReturnObject(ReturnNo.OK);
        }
        return returnObject;
    }

    /**
     * 重置用户密码
     * @param vo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject ResetUserPassword(PasswordResetVo vo)
    {
        //限制用户一段时间内只能发送一次验证码,验证redis有是否已经该用户发过
        //// TODO: 2021/12/24 如果这个加上去用例过不了
        ReturnObject returnlimit=new ReturnObject();//customerDao.LimitVisit(vo.getName());
        if(returnlimit.getCode()==ReturnNo.OK) {
            Customer customer = new Customer();
            customer.setUserName(vo.getName());
            ReturnObject returnObject = customerDao.selectUserByIndex(customer);
            if (returnObject.getData() == null) {
                return new ReturnObject(ReturnNo.CUSTOMERID_NOTEXIST);
            } else {
                //返回验证码
                List<CustomerPo> pos = (List<CustomerPo>) returnObject.getData();
                if(!(pos.size()>0))
                {
                    return new ReturnObject(ReturnNo.CUSTOMERID_NOTEXIST);
                }
                CustomerPo po= pos.get(0);
                ReturnObject returnObject1=customerDao.createCaptcha(po.getId());
                if(returnObject1.getData()!=null)
                {
                    String captcha=(String) returnObject1.getData();
                    //customerDao.sendEmail(captcha,po.getEmail());
                    return new ReturnObject(new CaptchaRetVo(captcha));
                }
                return returnObject1;
            }
        }
        else
        {
            return returnlimit;
        }

    }

    /**
     * 修改用户密码
     * @param vo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject changeUserPassword(NewPasswordVo vo)
    {
        //判断验证码是否正确
        ReturnObject returnUserId=customerDao.verifyCaptcha(vo.getCaptcha());
        if(returnUserId.getData()!=null) {
            Long userId=(Long)returnUserId.getData();
            CustomerPo userPo = (CustomerPo) customerDao.selectUserById(userId).getData();
            if (!userPo.getUserName().equals(vo.getUserName())) {
                return new ReturnObject(ReturnNo.CUSTOMERID_NOTEXIST);
            }
            //判断用户密码是否重复
            ReturnObject returndata = customerDao.selectUserById(userId);
            if (returndata.getData() == null) {
                return returndata;
            }
            CustomerPo po = (CustomerPo) returndata.getData();
            //判断是否和旧密码重复
            if (po.getPassword().equals(vo.getNewPassword())) {
                return new ReturnObject(ReturnNo.CUSTOMER_PASSWORDSAME);
            }
            //修改用户密码
            Customer customer = new Customer();
            customer.setId(userId);
            customer.setPassword(vo.getNewPassword());
            customer.setState(Customer.State.NORAML.getCode());
            ReturnObject returnObject = customerDao.updateUser(customer);
            if (returnObject.getData() != null) {
                return new ReturnObject(ReturnNo.OK);
            }
            return returnObject;
        }
        return returnUserId;
    }

    /**
     * 管理员封禁用户
     * @param userId
     * @param modifierId
     * @param modifierName
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject banUser(Long userId,Long modifierId,String modifierName)
    {
        Customer customer=new Customer();
        customer.setId(userId);
        setPoModifiedFields(customer,modifierId,modifierName);
        customer.setState(Customer.State.FORBIDDEN.getCode());
        ReturnObject returnCustomer=customerDao.selectUserById(userId);
        if(returnCustomer.getData()==null) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        }
        CustomerPo customerPo=(CustomerPo)returnCustomer.getData();
        if(customerPo.getState().equals(Customer.State.FORBIDDEN.getCode())) {
            return new ReturnObject(ReturnNo.STATENOTALLOW);
        }
        ReturnObject returnObject=customerDao.updateUser(customer);
        if(returnObject.getData()!=null)
        {
            return new ReturnObject(ReturnNo.OK);
        }
        return returnObject;
    }

    /**
     * 管理员解禁用户
     * @param userId
     * @param modifierId
     * @param modifierName
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject releaseUser(Long userId,Long modifierId,String modifierName)
    {
        Customer customer=new Customer();
        customer.setId(userId);
        setPoModifiedFields(customer,modifierId,modifierName);
        customer.setState(Customer.State.NORAML.getCode());
        ReturnObject returnCustomer=customerDao.selectUserById(userId);
        if(returnCustomer.getData()==null) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        }
        CustomerPo customerPo=(CustomerPo)returnCustomer.getData();
        if(customerPo.getState().equals(Customer.State.NORAML.getCode())) {
            return new ReturnObject(ReturnNo.STATENOTALLOW);
        }
        ReturnObject returnObject=customerDao.updateUser(customer);
        if(returnObject.getData()!=null)
        {
            return new ReturnObject(ReturnNo.OK);
        }
        return returnObject;
    }

    /**
     * 扣除用户积点
     * @param customerId
     * @param point
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject usePoint(Long customerId,Long point)
    {
        ReturnObject returnpoint=customerDao.selectUserById(customerId);
        if(returnpoint.getData()!=null)
        {
            /*如果积点为空，或者point小于等于0*/
            CustomerPo po=(CustomerPo) returnpoint.getData();
            if(po.getPoint()==null||po.getPoint()<0)
            {
                return new ReturnObject(new PointRetVo(0L));
            }
            else
            {
                Customer customer=cloneVo(po,Customer.class);
                //积点不够，直接扣光 返回扣了多少积点
                if(po.getPoint()<point)
                {
                    customer.setPoint(0L);
                    customerDao.updateUser(customer);
                    return new ReturnObject(new PointRetVo(po.getPoint()));
                }
                else
                {
                    customer.setPoint(customer.getPoint()-point);
                    customerDao.updateUser(customer);
                    return new ReturnObject(new PointRetVo(point));
                }
            }
        }
        else {
                return returnpoint;
        }
    }

    /**
     * 退回/新增用户积点
     * @param customerId
     * @param point
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject refundPoint(Long customerId,Long point)
    {
        ReturnObject returnpoint=customerDao.selectUserById(customerId);
        if(returnpoint.getData()!=null)
        {
            CustomerPo po=(CustomerPo) returnpoint.getData();
            Customer customer=cloneVo(po,Customer.class);
            //有溢出
           if(Long.MAX_VALUE-point<customer.getPoint())
           {
               customer.setPoint(Long.MAX_VALUE);
           }
           else
           {
               Long newpoint=customer.getPoint();
               customer.setPoint(newpoint+point);
           }
           ReturnObject returnObject=customerDao.updateUser(customer);
           return new ReturnObject(new PointRetVo((customer.getPoint())));
        }
        else
        {
            return returnpoint;
        }
    }
    public ReturnObject getSimpleCustomerInfo(Long customerId)
    {
        ReturnObject returnObject=customerDao.selectUserById(customerId);
        if(returnObject.getData()==null)
        {
            return returnObject;
        }
        CustomerPo po=(CustomerPo) returnObject.getData();
        SimpleCustomerRetVo vo=cloneVo(po,SimpleCustomerRetVo.class);
        return new ReturnObject(vo);
    }

    public void addCustomerPoint(Long id, Long point) {
        customerDao.addCustomerPoint(id,point);
    }
}
